/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package pt.ua.miect.sd.simuladorpesca.conns;

import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
import pt.ua.miect.sd.simuladorpesca.config.NodeService;

/**
 * The connection hub stores the connections to
 * @author PedroA
 */
public class ConnectionHub {
    private static ConnectionHub singleton;

    private ConcurrentHashMap<NodeService, SocketWrapper> allsockets;
    private ConcurrentHashMap<NodeService, Semaphore> allsemaphores;

    private  ConnectionHub()
    {
        allsemaphores = new ConcurrentHashMap<NodeService, Semaphore>();
        allsockets = new ConcurrentHashMap<NodeService, SocketWrapper>();
    }

    /**
     * Gets a singleton instance of the connection hub
     * @return returns instance of the connection hub
     */
    public static ConnectionHub getConnectionHub()
    {
        if (singleton == null)
        {
             singleton = new ConnectionHub();
        }
        return singleton;

    }

    /***
     * Adds a connection to the hub
     * @param service the service that is connected
     * @param sw the socket
     */
    public synchronized  void setConnection(NodeService service,SocketWrapper sw)
    {
        Semaphore sem = new Semaphore(1);
        allsockets.put(sw.getService(), sw);
        allsemaphores.put(sw.getService(), sem);
    }

    /***
     * sends a message to a target node
     * @param service
     * @param sm
     * @throws InterruptedException
     * @throws IOException
     */
    public void sendMessage(NodeService service, SocketMessage sm) throws InterruptedException, IOException
    {
        Semaphore sem = allsemaphores.get(service);
        sem.tryAcquire(1, TimeUnit.SECONDS);
        allsockets.get(service).getOut().writeObject(sm);
        sem.release();

    }

    public IMessageContent getMessage(NodeService service) throws ClassNotFoundException, IOException, InterruptedException
    {
        Semaphore sem = allsemaphores.get(service);
        sem.tryAcquire(1, TimeUnit.SECONDS);
        IMessageContent msg = (IMessageContent)allsockets.get(service).getIn().readObject();
        sem.release();
        return msg;
    }

}
